package com.ebspp.client.serverManager;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.ebspp.thrift.ResourceType;

/**
 * It is under construction
 * It is used for recording all the connection information for debug and online analyze uses.
 * @author x23pan
 *
 */
public class StatisticsDB implements IStat
{
	Map<String, Float> msgDelay;
	Map<String, Float> writeDelayPerMB;
	Map<String, Float> readDelayPerMB;
	Map<String, Map<ResourceType, Integer>> writeFail;
	Map<String, Map<ResourceType, Integer>> readFail;
	Map<String, Map<ResourceType, Integer>> serverResMap;
	Set<String> fatal;
	
	
	public StatisticsDB()
	{
		msgDelay = Collections.synchronizedMap(new HashMap<String, Float>());
		writeDelayPerMB = Collections.synchronizedMap(new HashMap<String, Float>());
		readDelayPerMB = Collections.synchronizedMap(new HashMap<String, Float>());
		
		writeFail = Collections.synchronizedMap(new HashMap<String, Map<ResourceType, Integer>>());
		readFail = Collections.synchronizedMap(new HashMap<String, Map<ResourceType, Integer>>());
		fatal = Collections.synchronizedSet(new HashSet<String>());
		
		serverResMap = Collections.synchronizedMap(new HashMap<String, Map<ResourceType, Integer>>());
	}
	
	@Override
	public void setMsgDelay(String server, float duration) {
		// TODO Auto-generated method stub
		if(msgDelay.get(server) == null)
			msgDelay.put(server, duration);
		else
		{
			float delay = msgDelay.get(server);
			delay = delay * (float)0.5 + duration * (float)0.5;
			msgDelay.put(server, delay);
		}
	}

	@Override
	public void setWriteDelay(String server, float duration, int amount,
			ResourceType resType) {
		// TODO Auto-generated method stub
		if(writeDelayPerMB.get(server) == null)
			writeDelayPerMB.put(server, amount/duration);
		else
		{
			float delay = writeDelayPerMB.get(server);
			delay = delay * (float)0.5 + amount/duration * (float)0.5;
			writeDelayPerMB.put(server, delay);
		}
	}

	@Override
	public void setReadDelay(String server, float duration, int amount,
			ResourceType resType) {
		// TODO Auto-generated method stub
		if(readDelayPerMB.get(server) == null)
			readDelayPerMB.put(server, amount/duration);
		else
		{
			float delay = readDelayPerMB.get(server);
			delay = delay * (float)0.5 + amount/duration * (float)0.5;
			readDelayPerMB.put(server, delay);
		}
	}

	@Override
	public void setWriteFail(String server, ResourceType resType, int amount) {
		// TODO Auto-generated method stub
		if(writeFail.get(server) == null)
		{
			Map<ResourceType, Integer> resMap = 
					Collections.synchronizedMap(new HashMap<ResourceType, Integer>());
			resMap.put(resType, amount);
			writeFail.put(server, resMap);
		}
		else
		{
			Map<ResourceType, Integer> resMap = writeFail.get(server);
			if(resMap.get(resType) == null)
				resMap.put(resType, amount);
			else
				resMap.put(resType, resMap.get(resType)+amount);
		}
	}

	@Override
	public void setReadFail(String server, ResourceType resType, int amount) {
		// TODO Auto-generated method stub
		if(readFail.get(server) == null)
		{
			Map<ResourceType, Integer> resMap = 
					Collections.synchronizedMap(new HashMap<ResourceType, Integer>());
			resMap.put(resType, amount);
			readFail.put(server, resMap);
		}
		else
		{
			Map<ResourceType, Integer> resMap = readFail.get(server);
			if(resMap.get(resType) == null)
				resMap.put(resType, amount);
			else
				resMap.put(resType, resMap.get(resType)+amount);
		}
	}

	@Override
	public void setFatal(String server) {
		// TODO Auto-generated method stub
		fatal.add(server);
	}

	@Override
	public void setResource(String server, Map<ResourceType, Integer> resource) {
		// TODO Auto-generated method stub
		if(serverResMap.get(server) == null)
			serverResMap.put(server, Collections.synchronizedMap(new HashMap<ResourceType, Integer>()));
		
		Map<ResourceType, Integer> resMap = serverResMap.get(server);
		for(ResourceType type : ResourceType.values())
			resMap.put(type, resource.get(type));
	}

}
